package com.legendframework.core.ioc;

import com.legendframework.core.Store;
import com.legendframework.core.ioc.annotation.Bean;
import com.legendframework.core.ioc.exception.BeansException;
import com.legendframework.core.AbstractLegendPlugin;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Bean操作的主函数
 */
public class BeansFactoryManager {

    /**
     * Bean构建注解实现类
     */
    private final Map<Class<?>,BeansGenerate> beansGenerates = new HashMap<>();

    private final Store store;

    public BeansFactoryManager(Store store) {
        this.store = store;
    }

    public void addBeanGenerates(BeansGenerate beansGenerate){
        beansGenerates.put(beansGenerate.getClass(),beansGenerate);
    }

    public <T> T getBeansGenerate(Class<T> cls) {
        BeansGenerate beansGenerate = beansGenerates.get(cls);
        if (beansGenerate == null) {
            return null;
        }
        return (T) beansGenerate;
    }
    /**
     * 获取所有实例化的类注解方式
     * @return
     */
    public List<BeansGenerate> getBeansGenerates(){
        return new ArrayList<>(beansGenerates.values());
    }

    /**
     * 将这个字节码中的资源加入到模板池
     * @param aClass
     */
    public void addPool(Class<?> aClass , AbstractLegendPlugin plugin) {
        if (aClass == null) {
            return;
        }
        boolean flag = false;
        for (BeansGenerate beansGenerate : beansGenerates.values()) {
            if (aClass.isAnnotationPresent(beansGenerate.getAnnotation())) {
                flag = true;
            }
        }
        if (!flag) {
            return;
        }
        //Bean载入到模板池
        store.getBeansFactory().addClassPool(aClass , plugin);
        //函数载入到模板池
        try {
            Object obj = aClass.newInstance();
            for (Method declaredMethod : aClass.getDeclaredMethods()) {
                if (declaredMethod.isAnnotationPresent(Bean.class)) {
                    store.getBeansFactory().addClassPool(declaredMethod,obj , plugin);
                }
            }
        } catch (Throwable e) {
        }
    }

    /**
     * 构建这个字节码
     * @param cls
     */
    public Object generate(Class<?> cls , AbstractLegendPlugin plugin){
        for (BeansGenerate beansGenerate : beansGenerates.values()) {
            if (cls.isAnnotationPresent(beansGenerate.getAnnotation())){
                return beansGenerate.generateByOne(cls,plugin).getR2();
            }
        }
        throw new BeansException("这个类不支持构建, '"+String.valueOf(cls.getName())+"'");
    }

}
